﻿using System;
using System.Web;
using System.Net;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using Google.GData.Client;
using Google.GData.Photos;
using Google.GData.Extensions;
using Google.GData.Extensions.Location;
using Google.Picasa;

namespace PicasaTagger
{
    public partial class MainForm : Form
    {
        delegate void SetStatusCallback(string text);
        delegate void ClearTagListCallback();

        PicasaService service;
        string username;
        string password;
        Queue<PicasaPhoto> photoQueue;
        int queueLength = 10;
        PicasaPhoto currentPhoto;
        LoginForm loginForm;
        PicasaFeed currentUserAlbumFeed;

        public MainForm()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            txtEnterTag.Focus();

            ContextMenu tagListContextMenu = new ContextMenu();
            MenuItem removeItem = new MenuItem();

            photoQueue = new Queue<PicasaPhoto>(queueLength);

            

            loginForm = new LoginForm();
            if (loginForm.ShowDialog() == DialogResult.OK)
            {
                username = loginForm.GetUsername();
                password = loginForm.GetPassword();
                MessageBox.Show("Welcome " + username + ", " + password);

                service = new PicasaService("PicasaTagger");
                service.setUserCredentials(username, password);

                AlbumQuery query = new AlbumQuery(PicasaQuery.CreatePicasaUri(username));
                currentUserAlbumFeed = service.Query(query);

                Thread t = new Thread(() => LoadPhotos());
                t.Start();
            }
            
        }

        private void nextPhoto()
        {
            Thread t = new Thread(() => LoadPhotos());
            t.Start();

            if (photoQueue.Count != 0)
            {
                currentPhoto = photoQueue.Dequeue();
                ShowCurrentPhoto();
            }
            
        }

        private void ShowCurrentPhoto()
        {
            pbImageViewer.Image = currentPhoto.Image;

            ClearTagList();
            foreach (string tag in currentPhoto.TagList)
            {
                lbTagList.Items.Add(tag);
            }
            txtEnterTag.Clear();
            txtEnterTag.Focus();

            lbTagList.Enabled = true;
            pnlAddTag.Enabled = true;
        }

        private void SetStatus(string status)
        {
            if (statusStrip1.InvokeRequired)
            {
                SetStatusCallback d = new SetStatusCallback(SetStatus);
                this.Invoke(d, new object[] { status });
            }
            else
            {
                lblStatus.Text = status;
            }
        }

        private void ClearTagList()
        {
            if (lbTagList.InvokeRequired)
            {
                ClearTagListCallback d = new ClearTagListCallback(ClearTagList);
                this.Invoke(d);
            }
            else
            {
                lbTagList.Items.Clear();
            }
        }

        private void LoadPhotos()
        {
            while (photoQueue.Count < queueLength)
            {
                SetStatus("Loading image... (" + photoQueue.Count + "/" + queueLength + ")");
                

                Random r = new Random();
                int album = r.Next(currentUserAlbumFeed.Entries.Count);

                AlbumAccessor albumAcc = new AlbumAccessor((PicasaEntry)currentUserAlbumFeed.Entries.ElementAt(album));
                string currentAlbumId = albumAcc.Id;
                //lblPhotoLocation.Text = albumAcc.AlbumTitle + " -> ";
                PhotoQuery photoQuery = new PhotoQuery(PicasaQuery.CreatePicasaUri(username, albumAcc.Id));
                PicasaFeed photoFeed = service.Query(photoQuery);
                int photo = r.Next(photoFeed.Entries.Count);

                PicasaEntry photoEntry = (PicasaEntry)photoFeed.Entries.ElementAt(photo);
                PhotoAccessor photoAcc = new PhotoAccessor(photoEntry);
                string currentPhotoId = photoAcc.Id;

                // Get the photo
                HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(photoEntry.Media.Content.Url);
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                Image image = Image.FromStream(response.GetResponseStream());
                response.Close();

                // Get the tags
                TagQuery tagQuery = new TagQuery(PicasaQuery.CreatePicasaUri(username, albumAcc.Id, photoAcc.Id));
                PicasaFeed tagFeed = service.Query(tagQuery);

                List<string> tagList = new List<string>();
                foreach (PicasaEntry pe in tagFeed.Entries)
                {
                    tagList.Add(pe.Title.Text);
                }

                PicasaPhoto newPhoto = new PicasaPhoto(currentAlbumId, currentPhotoId, image, tagList);

                if (currentPhoto == null)
                {
                    // No current photo so use this one
                    currentPhoto = newPhoto;
                    ShowCurrentPhoto();
                }
                else
                {
                    // Already a photo ready, put this one in queue
                    photoQueue.Enqueue(newPhoto);
                }

                
            }
            SetStatus("Done");
        }

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            nextPhoto();
        }

        private void cmdAdd_Click(object sender, EventArgs e)
        {
            AddNewTag();
        }

        private void AddNewTag()
        {
            //Get the new tag
            String newTag = txtEnterTag.Text;

            //Check if it already exists
            if (!lbTagList.Items.Contains(newTag))
            {
                //Copy tags to ArrayList for sorting
                ArrayList arrayList = new ArrayList();
                foreach (string tag in lbTagList.Items)
                {
                    arrayList.Add(tag);
                }
                arrayList.Add(newTag);
                //Sort
                arrayList.Sort();

                lbTagList.Items.Clear();

                //Add back into listbox
                foreach (string tag in arrayList)
                {
                    lbTagList.Items.Add(tag);
                }
                txtEnterTag.Clear();
                txtEnterTag.Focus();

                Thread t = new Thread(() => PostTagToPicasa(service, username, currentPhoto.AlbumID, currentPhoto.PhotoID, newTag));
                t.Start();
            }
        }




        private void txtEnterTag_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                AddNewTag();
            }
        }

        private void PostTagToPicasa(PicasaService service, string username, string albumid, string photoid, string tag)
        {
            SetStatus("Uploading tag " + tag);
            Uri postUri = new Uri(PicasaQuery.CreatePicasaUri(username, albumid, photoid));

            TagEntry newEntry = new TagEntry();

            newEntry.Title.Text = tag;

            try
            {
                PicasaEntry createdEntry = (PicasaEntry)service.Insert(postUri, newEntry);
            }
            catch (GDataRequestException e)
            {
                //
            }
            SetStatus("Done");
        }
    }
}
